package com.jcbase.test;

import java.util.Calendar;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.ForkJoinTask;
import java.util.concurrent.RecursiveTask;

/**
 * TODO: 增加描述
 * 
 * @author yiz
 * @date 2016年8月11日 下午3:52:51
 * @version 1.0.0 
 * @copyright pycredit.cn 
 */
public class CalculatorFork extends RecursiveTask<Integer> {

	/**
	 * 
	 */
	private static final long serialVersionUID = -5844437722692371468L;
	private static final int THRESHOLD = 2;//阈值
	private int start;
	private int end;

	public CalculatorFork(int start, int end) {
		this.start = start;
		this.end = end;
	}

	@Override
	protected Integer compute() {
		int sum = 0;
		//如果任务足够小就计算任务
		boolean canCompute = (end - start) <= THRESHOLD;
		System.out.println("start===" + (end - start));
		if (canCompute) {
			for (int i = start; i <= end; i++) {
				sum += i;
			}
			System.out.println("计算 start=" + start + "=======end=" + end);
		} else {
			System.out.println("开始拆分start=" + start + "======end=" + end);
			//如果任务大于阀值，就分裂成两个子任务计算
			int middle = (start + end) / 2;
			CalculatorFork leftTask = new CalculatorFork(start, middle);
			CalculatorFork rightTask = new CalculatorFork(middle + 1, end);
			//执行子任务
			leftTask.fork();
			rightTask.fork();
			//等待子任务执行完，并得到其结果
			int leftResult = leftTask.join();
			int rightResult = rightTask.join();
			//合并子任务
			sum = leftResult + rightResult;
			System.out.println("结束拆分start=" + start + "====end=" + end);
		}
		return sum;
	}

	public static void main(String[] args) {
		long startTime = Calendar.getInstance().getTimeInMillis();
		ForkJoinPool forkJoinPool = new ForkJoinPool();

		//生成一个计算任务，负责计算1+2+3+4

		CalculatorFork task = new CalculatorFork(1, 4);

		//执行一个任务

		ForkJoinTask<Integer> result = forkJoinPool.submit(task);

		try {

			System.out.println(result.get());

		} catch (InterruptedException e) {

		} catch (ExecutionException e) {

		}
		System.out.println(Calendar.getInstance().getTimeInMillis() - startTime);

	}

}
